home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Diamond Collection / The Diamond Collection (Software Vault)(Digital Impact).ISO / cdr44 / xlib06p1.zip / XSCALEBM.CPP < prev    next >
C/C++ Source or Header  |  1995-03-15  |  9KB  |  277 lines

  1. #include "xinternl.h"
  2. #include <conio.h>
  3. /*==================================================================
  4. XSCALEBM.CPP contains the basic functions for bitmap scaling in
  5. mode X.
  6.  
  7. These routines were written initially by John P. Slagel and
  8. company and modified March 1995 by Victor B. Putz.
  9. ===================================================================*/
  10.  
  11. extern xScreenCoord_t LeftClip;
  12. extern xScreenCoord_t RightClip;
  13. extern xScreenCoord_t TopClip;
  14. extern xScreenCoord_t BottomClip;
  15.  
  16. extern int ScrnLogicalByteWidth;
  17.  
  18. extern BYTE * pbVGABuffer;
  19.  
  20. void x_scale_bm(
  21.   xScreenCoord_t iDestX,
  22.   xScreenCoord_t iDestY,
  23.   int iDestWidth,
  24.   int iDestHeight,
  25.   xPageHandle_t ScrnOffs,
  26.   BYTE * pbData
  27. )
  28. {
  29.     //get width and height;
  30.   int iSourceWidth = *pbData++;
  31.   int iSourceHeight = *pbData++;
  32.   //now check for "too small" puts ( width or height < 2 )
  33.   if ( ( iDestWidth < 2 ) ||
  34.     ( iDestHeight < 2 ) ) {
  35.     return;
  36.   }
  37.   //now check for out-of-bounds puts, basing of pixel-sized clipping
  38.   //boundaries ( rather than nibble-sized clipping boundaries )
  39.   int iLeftPixelClip = LeftClip << 2;
  40.   int iRightPixelClip = RightClip << 2;
  41.   if ( ( iDestY > BottomClip ) ||
  42.     ( ( iDestY + iDestHeight - 1 ) < TopClip ) ||
  43.     ( iDestX > iRightPixelClip ) ||
  44.     ( ( iDestY + iDestWidth - 1 ) < iLeftPixelClip ) ) {
  45.         return;
  46.   }
  47.   //for now, clipped width = destination width, set up decision X variable
  48.   int iClippedWidth = iDestWidth;
  49.   int iDecisionX = -iDestWidth;
  50.   //clipped height and decision Y variable
  51.   int iClippedHeight = iDestHeight;
  52.   int iDecisionY = -iDestHeight;
  53.   //...and offset into source map
  54.   int iSourceOffset = 0;
  55.   //check for clipping in the Y axis, first checking top
  56.   if ( iDestY < TopClip ) {
  57.     int iClippedRows = TopClip - iDestY;
  58.     iClippedHeight -= iClippedRows;
  59.     iDestY = TopClip;
  60.     for ( int i = iClippedRows; i > 0; --i ) {
  61.       iDecisionY += iSourceHeight;
  62.       if ( iDecisionY >= 0 ) {
  63.           while ( iDecisionY >= 0 ) {
  64.                     iDecisionY -= iDestHeight;
  65.                     iSourceOffset += iSourceWidth;
  66.           }
  67.       }
  68.     }
  69.   }
  70.   //then checking bottom...
  71.   int iBottomRow = iDestY + iClippedHeight - 1;
  72.   if ( iBottomRow > BottomClip ) {
  73.     iClippedHeight -= ( iBottomRow - BottomClip );
  74.   }
  75.   //then check for left clipping...
  76.   if ( iDestX < iLeftPixelClip ) {
  77.     int iClippedColumns = iLeftPixelClip - iDestX;
  78.     iClippedWidth -= iClippedColumns;
  79.     iDestX = iLeftPixelClip;
  80.     for ( int i = iClippedColumns; i > 0; --i ) {
  81.       iDecisionX += iSourceWidth;
  82.       if ( iDecisionX >= 0 ) {
  83.         while ( iDecisionX >= 0 ) {
  84.                   iDecisionX -= iDestWidth;
  85.                   iSourceOffset++;
  86.         }
  87.       }
  88.     }
  89.   }
  90.   int iRightRow = iDestX + iClippedWidth - 1;
  91.   if ( iRightRow > iRightPixelClip ) {
  92.     iClippedWidth -= ( iRightRow - iRightPixelClip );
  93.   }
  94.  
  95.   //Okay!  The clipping is done, so let's find our source and
  96.   //destination pointers.
  97.   BYTE * pbDest = pbVGABuffer + ScrnOffs + ( ScrnLogicalByteWidth * iDestY ) + iDestX / 4;
  98.   BYTE * pbSource = pbData + iSourceOffset;
  99.   int iWidthCounter = iClippedWidth;
  100.   //set up the controller to switch planes
  101.   outp( SC_INDEX, MAP_MASK );
  102.   int iPlane = iDestX & 0x03;
  103.   outp( SC_INDEX + 1, 1 << iPlane );
  104.   //now set up some "old position" pointers so we can rewind reliably
  105.   BYTE * pbDestStart = pbDest;
  106.   BYTE * pbSourceStart = pbSource;
  107.  
  108.   while ( iWidthCounter-- ) {
  109.     int iHeightCounter = iClippedHeight;
  110.     int iDecisionYCount = iDecisionY;
  111.     BYTE b = *pbSource;
  112.     while ( iHeightCounter-- ) {
  113.         //plot the pixel and go to the next pixel down.
  114.             *pbDest = b;
  115.             pbDest += ScrnLogicalByteWidth;
  116.       //now increment our decision Y variable and get the next source
  117.       //pixel if need be
  118.       iDecisionYCount += iSourceHeight;
  119.       if ( iDecisionYCount >= 0 ) {
  120.           while ( iDecisionYCount >= 0 ) {
  121.                     iDecisionYCount -= iDestHeight;
  122.                     pbSource += iSourceWidth;
  123.           }
  124.                 b = *pbSource;
  125.       }
  126.     }
  127.     //now go to the next screen column
  128.     ++iPlane;
  129.     //if we've wrapped over our 4-plane boundary, increase the VGA start
  130.     //by one pixel.
  131.     if ( iPlane & 0x04 ) {
  132.       pbDestStart++;
  133.       iPlane &= 0x03;
  134.     }
  135.     outp( SC_INDEX + 1, 1 << iPlane );
  136.     pbDest = pbDestStart;
  137.     //now increment our decision X variable and go to the next source column
  138.         //if need be;
  139.     iDecisionX += iSourceWidth;
  140.     if ( iDecisionX >= 0 ) {
  141.       while ( iDecisionX >= 0 ) {
  142.                 iDecisionX -= iDestWidth;
  143.                 pbSourceStart++;
  144.       }
  145.     }
  146.     pbSource = pbSourceStart;
  147.   }
  148. }
  149.  
  150. /*
  151. The scaling version of the routine is the exact same code, with the addition
  152. of a check to make sure the color is not zero before blitting.
  153. */
  154. void x_scale_masked_bm(
  155.   xScreenCoord_t iDestX,
  156.   xScreenCoord_t iDestY,
  157.   int iDestWidth,
  158.   int iDestHeight,
  159.   xPageHandle_t ScrnOffs,
  160.   BYTE * pbData
  161. )
  162. {
  163.     //get width and height;
  164.   int iSourceWidth = *pbData++;
  165.   int iSourceHeight = *pbData++;
  166.   //now check for "too small" puts ( width or height < 2 )
  167.   if ( ( iDestWidth < 2 ) ||
  168.     ( iDestHeight < 2 ) ) {
  169.     return;
  170.   }
  171.   //now check for out-of-bounds puts, basing of pixel-sized clipping
  172.   //boundaries ( rather than nibble-sized clipping boundaries )
  173.   int iLeftPixelClip = LeftClip << 2;
  174.   int iRightPixelClip = RightClip << 2;
  175.   if ( ( iDestY > BottomClip ) ||
  176.     ( ( iDestY + iDestHeight - 1 ) < TopClip ) ||
  177.     ( iDestX > iRightPixelClip ) ||
  178.     ( ( iDestX + iDestWidth - 1 ) < iLeftPixelClip ) ) {
  179.         return;
  180.   }
  181.   //for now, clipped width = destination width, set up decision X variable
  182.   int iClippedWidth = iDestWidth;
  183.   int iDecisionX = -iDestWidth;
  184.   //clipped height and decision Y variable
  185.   int iClippedHeight = iDestHeight;
  186.   int iDecisionY = -iDestHeight;
  187.   //...and offset into source map
  188.   int iSourceOffset = 0;
  189.   //check for clipping in the Y axis, first checking top
  190.   if ( iDestY < TopClip ) {
  191.     int iClippedRows = TopClip - iDestY;
  192.     iClippedHeight -= iClippedRows;
  193.     iSourceOffset += iClippedRows * iSourceWidth;
  194.     iDestY = TopClip;
  195.     iDecisionY += iClippedRows * iSourceHeight;
  196.     while ( iDecisionY > 0 ) {
  197.       iDecisionY -= iDestHeight;
  198.     }
  199.   }
  200.   //then checking bottom...
  201.   int iBottomRow = iDestY + iClippedHeight - 1;
  202.   if ( iBottomRow > BottomClip ) {
  203.     iClippedHeight -= ( iBottomRow - BottomClip );
  204.   }
  205.   //then check for left clipping...
  206.   if ( iDestX < iLeftPixelClip ) {
  207.     int iClippedColumns = iLeftPixelClip - iDestX;
  208.     iClippedWidth -= iClippedColumns;
  209.     iSourceOffset += iClippedColumns;
  210.     iDestX = iLeftPixelClip;
  211.     iDecisionX += iClippedColumns * iSourceWidth;
  212.     while ( iDecisionX > 0 ) {
  213.       iDecisionX -= iDestWidth;
  214.     }
  215.   }
  216.   int iRightRow = iDestX + iClippedWidth - 1;
  217.   if ( iRightRow > iRightPixelClip ) {
  218.     iClippedWidth -= ( iRightRow - iRightPixelClip );
  219.   }
  220.  
  221.   //Okay!  The clipping is done, so let's find our source and
  222.   //destination pointers.
  223.   BYTE * pbDest = pbVGABuffer + ScrnOffs + ( ScrnLogicalByteWidth * iDestY ) + iDestX / 4;
  224.   BYTE * pbSource = pbData + iSourceOffset;
  225.   int iWidthCounter = iClippedWidth;
  226.   //set up the controller to switch planes
  227.   outp( SC_INDEX, MAP_MASK );
  228.   int iPlane = iDestX & 0x03;
  229.   outp( SC_INDEX + 1, 1 << iPlane );
  230.   //now set up some "old position" pointers so we can rewind reliably
  231.   BYTE * pbDestStart = pbDest;
  232.   BYTE * pbSourceStart = pbSource;
  233.  
  234.   while ( iWidthCounter-- ) {
  235.     int iHeightCounter = iClippedHeight;
  236.     int iDecisionYCount = iDecisionY;
  237.     BYTE b = *pbSource;
  238.     while ( iHeightCounter-- ) {
  239.         //plot the pixel and go to the next pixel down.
  240.         if ( b != 0 ) {
  241.                 *pbDest = b;
  242.       }
  243.             pbDest += ScrnLogicalByteWidth;
  244.       //now increment our decision Y variable and get the next source
  245.       //pixel if need be
  246.       iDecisionYCount += iSourceHeight;
  247.       if ( iDecisionYCount >= 0 ) {
  248.           while ( iDecisionYCount >= 0 ) {
  249.                     iDecisionYCount -= iDestHeight;
  250.                     pbSource += iSourceWidth;
  251.           }
  252.                 b = *pbSource;
  253.       }
  254.     }
  255.     //now go to the next screen column
  256.     ++iPlane;
  257.     //if we've wrapped over our 4-plane boundary, increase the VGA start
  258.     //by one pixel.
  259.     if ( iPlane & 0x04 ) {
  260.       pbDestStart++;
  261.       iPlane &= 0x03;
  262.     }
  263.     outp( SC_INDEX + 1, 1 << iPlane );
  264.     pbDest = pbDestStart;
  265.     //now increment our decision X variable and go to the next source column
  266.         //if need be;
  267.     iDecisionX += iSourceWidth;
  268.     if ( iDecisionX >= 0 ) {
  269.       while ( iDecisionX >= 0 ) {
  270.                 iDecisionX -= iDestWidth;
  271.                 pbSourceStart++;
  272.       }
  273.     }
  274.     pbSource = pbSourceStart;
  275.   }
  276. }
  277.